package com.example.springboottest.bootable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;

@Component
public class BootLoader implements ApplicationContextAware, ApplicationListener<ApplicationReadyEvent> {

    private static final Logger logger = LoggerFactory.getLogger(BootLoader.class);

    private ConfigurableApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (applicationContext instanceof ConfigurableApplicationContext) {
            context = (ConfigurableApplicationContext) applicationContext;
        }
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {

        // 初始化所有实现BootableService的业务服务
        Map<String, BootableHandler> beanMap = context.getBeansOfType(BootableHandler.class);
        List<BootableHandler> svcList = new ArrayList<BootableHandler>();

        if (beanMap != null && beanMap.size() > 0) {
            Iterator<String> it = beanMap.keySet().iterator();
            while (it.hasNext()) {
                BootableHandler svc = beanMap.get(it.next());
                svcList.add(svc);
            }
        }

        svcList.sort((e1, e2) -> {
            int result = Integer.valueOf(e1.getInitOrder()).compareTo(Integer.valueOf(e2.getInitOrder()));
            return result;
        });

        if (logger.isInfoEnabled()) {
            String sortMessage = "";
            for (BootableHandler bs : svcList) {
                Class<?> objClass = AopUtils.getTargetClass(bs);
                sortMessage += String.format("%6d: %-30s (%s)\n", bs.getInitOrder(), objClass.getSimpleName(), objClass.getName());
            }
            logger.info("BootableService initCluster order: \n" + sortMessage);
        }

        // 在执行初始化时，如果抛出异常，则认为该服务初始化失败。
        svcList.forEach(bs -> {
            try {
                bs.doInit();
            } catch (Exception e) {
                logger.error(bs.toString() + "初始化失败:", e);
            }
        });

        logger.info("Server started on port: {}", context.getEnvironment().getProperty("local.server.port"));
    }
}
